/*
 * Tranquil Java Integrated Development Environment
 *
 * The GNU General Public License Version 3
 *
 * Copyright (C) 2021 Autumn Lamonte
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Autumn Lamonte [AutumnWalksTheLake@gmail.com] ⚧ Trans Liberation Now
 * @version 1
 */
package tjide.project;

import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import tjide.build.CompileListener;
import tjide.build.CompileTask;

/**
 * TextFileTarget represents a plain text file.
 */
public class TextFileTarget extends FileTarget implements CompileTask {

    // ------------------------------------------------------------------------
    // Variables --------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Compile start time.
     */
    private long compileStartTime;

    /**
     * Compile running flag.
     */
    private boolean compileRunning = false;

    // ------------------------------------------------------------------------
    // Constructors -----------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Public constructor.
     *
     * @param name the source filename, relative to the project's source
     * directory name.  This will also be the name seen in the project
     * window.
     */
    public TextFileTarget(final String name) {

        super(name, name);
    }

    // ------------------------------------------------------------------------
    // FileTarget -------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Make human-readable description of this target.
     *
     * @return displayable String
     */
    @Override
    public String toString() {
        return name;
    }

    /**
     * Compile the target.
     *
     * @param project the project metadata
     */
    @Override
    public void compile(final Project project) {
        compileStartTime = System.currentTimeMillis();
        compileRunning = true;

        for (CompileListener listener: compileListeners) {
            listener.setCompileBegin();
            listener.setCompileTask(this);
            listener.setCompileFile(name, buildFilename);
            listener.setCompileLineCount(getSourceLineCount(project));
            listener.setCompileAvailableMemory(Runtime.getRuntime().
                freeMemory() / 1024);
        }

        // For a text file, copy from source to build.
        try {
            File outputFile = new File(project.getFullBuildDir(),
                buildFilename);
            File buildDir = outputFile.getParentFile();
            if (!buildDir.exists()) {
                buildDir.mkdirs();
            }

            File inputFile = new File(project.getFullSourceDir(),
                name);
            if (outputFile.equals(inputFile)) {
                // Do not overwrite the input file, just call this success.
                for (CompileListener listener: compileListeners) {
                    listener.setCompileSucceeded(true);
                }
                return;
            }

            FileInputStream input = new FileInputStream(inputFile);
            FileOutputStream output = new FileOutputStream(outputFile);
            byte [] buffer = new byte[1024];
            while (true) {
                int n = input.read(buffer, 0, buffer.length);
                if (n <= 0) {
                    break;
                }
                output.write(buffer, 0, n);
            }
            input.close();
            output.close();

            for (CompileListener listener: compileListeners) {
                listener.setCompileSucceeded(true);
            }
        } catch (IOException e) {
            project.displayException(e);

            for (CompileListener listener: compileListeners) {
                listener.setCompileFailed(true);
            }
        } finally {
            compileRunning = false;
        }
    }

    /**
     * When this target is run, go to a specific line location.
     *
     * @param line the line number
     */
    @Override
    public void runToLocation(final int line) {
        // This does nothing for a text file.
    }

    // ------------------------------------------------------------------------
    // CompileTask ------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Cancel an in-progress compile.  Does nothing if the compile is not
     * actually running.  Note that the internal compiler cannot be canceled.
     */
    public void cancelCompile() {
        // NOP
    }

    /**
     * Determine if compile is in progress.
     *
     * @return true if the compile is in progress
     */
    public boolean isCompileRunning() {
        return compileRunning;
    }

    /**
     * Get the start time of the compile task.
     *
     * @return the system time (millis) the compile task started
     */
    public long getCompileStartTime() {
        return compileStartTime;
    }

    /**
     * Get the target of the compile task.
     *
     * @return the target of the compile task
     */
    public Target getTarget() {
        return this;
    }

}
